package generics

type (
	// ZeroStruct 空結構
	ZeroStruct = struct{}

	// TMap 泛型字典
	TMap[K comparable, V any] map[K]V
)

// Zero 空結構對象
var Zero = ZeroStruct{}

// List 構造泛型字典, 可安全傳入 nil 值
func Map[K comparable, V any](m map[K]V) TMap[K, V] {
	if m == nil {
		return TMap[K, V]{}
	} else {
		return TMap[K, V](m)
	}
}

// Set 構造泛型集合, 可安全傳入 nil 值
func Set[T comparable](m map[T]ZeroStruct) TMap[T, ZeroStruct] {
	return Map(m)
}

// Len 返回長度
func (m TMap[K, V]) Len() int {
	return len(m)
}

// Empty 字典是否爲空
func (m TMap[K, V]) Empty() bool {
	return m.Len() == 0
}

// Delete 移除元素
func (m TMap[K, V]) Delete(key K) TMap[K, V] {
	delete(m, key)
	return m
}

// Filter 過濾元素, 不滿足的 filter 的鍵值對將被移除
func (m TMap[K, V]) Filter(filter func(key K, value V) bool) TMap[K, V] {
	removeKeys := []K{}
	for key, value := range m {
		if !filter(key, value) {
			removeKeys = append(removeKeys, key)
		}
	}
	for _, key := range removeKeys {
		delete(m, key)
	}
	return m
}

// ForEach 遍歷處理所有鍵值對
func (m TMap[K, V]) ForEach(handle func(key K, value V) error) (succeeded int, err error) {
	for key, value := range m {
		err = handle(key, value)
		if err != nil {
			return
		}
		succeeded++
	}
	return
}

// Root 獲取根對象
func (m TMap[K, V]) Root() map[K]V {
	return m
}

// Keys 返回所有鍵名列表
func (m TMap[K, V]) Keys() (list TList[K]) {
	list = make([]K, 0, len(m))
	for key := range m {
		list = append(list, key)
	}
	return
}

// Values 返回所有鍵值列表
//
//   - TMap[K, V] 之 V 不滿足 comparable 約束, 故不能直接轉爲 List[V]
//   - 但在具體場景中可通過 List(m.Values()) 在滿足約束的條件下轉換
func (m TMap[K, V]) Values() (list []V) {
	list = make([]V, 0, len(m))
	for _, value := range m {
		list = append(list, value)
	}
	return
}
